home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / rcs5ap1s.lzh / RCSLEX.C < prev    next >
C/C++ Source or Header  |  1991-01-30  |  25KB  |  1,001 lines

  1. /*
  2.  *                     RCS file input
  3.  */
  4. /*********************************************************************************
  5.  *                     Lexical Analysis.
  6.  *                     hashtable, Lexinit, nextlex, getlex, getkey,
  7.  *                     getid, getnum, readstring, printstring, savestring,
  8.  *                     checkid, fatserror, error, faterror, warn, diagnose
  9.  *                     Testprogram: define LEXDB
  10.  *********************************************************************************
  11.  */
  12.  
  13. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  14.    Copyright 1990 by Paul Eggert
  15.    Distributed under license by the Free Software Foundation, Inc.
  16.  
  17. This file is part of RCS.
  18.  
  19. RCS is free software; you can redistribute it and/or modify
  20. it under the terms of the GNU General Public License as published by
  21. the Free Software Foundation; either version 1, or (at your option)
  22. any later version.
  23.  
  24. RCS is distributed in the hope that it will be useful,
  25. but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27. GNU General Public License for more details.
  28.  
  29. You should have received a copy of the GNU General Public License
  30. along with RCS; see the file COPYING.  If not, write to
  31. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  32.  
  33. Report problems and direct all questions to:
  34.  
  35.     rcs-bugs@cs.purdue.edu
  36.  
  37. */
  38.  
  39.  
  40.  
  41. /* $Log: rcslex.c,v $
  42.  * Revision 5.6  1991/01/30  14:21:32  apratt
  43.  * CI with RCS version 5
  44.  *
  45.  * Revision 5.5  90/12/04  05:18:47  eggert
  46.  * checked in with -k by apratt at 91.01.10.13.15.22.
  47.  * 
  48.  * Revision 5.5  1990/12/04  05:18:47  eggert
  49.  * Use -I for prompts and -q for diagnostics.
  50.  *
  51.  * Revision 5.4  1990/11/19  20:05:28  hammer
  52.  * no longer gives warning about unknown keywords if -q is specified
  53.  *
  54.  * Revision 5.3  1990/11/01  05:03:48  eggert
  55.  * When ignoring unknown phrases, copy them to the output RCS file.
  56.  *
  57.  * Revision 5.2  1990/09/04  08:02:27  eggert
  58.  * Count RCS lines better.
  59.  *
  60.  * Revision 5.1  1990/08/29  07:14:03  eggert
  61.  * Work around buggy compilers with defective argument promotion.
  62.  *
  63.  * Revision 5.0  1990/08/22  08:12:55  eggert
  64.  * Remove compile-time limits; use malloc instead.
  65.  * Report errno-related errors with perror().
  66.  * Ansify and Posixate.  Add support for ISO 8859.
  67.  * Use better hash function.
  68.  *
  69.  * Revision 4.6  89/05/01  15:13:07  narten
  70.  * changed copyright header to reflect current distribution rules
  71.  * 
  72.  * Revision 4.5  88/08/28  15:01:12  eggert
  73.  * Don't loop when writing error messages to a full filesystem.
  74.  * Flush stderr/stdout when mixing output.
  75.  * Yield exit status compatible with diff(1).
  76.  * Shrink stdio code size; allow cc -R; remove lint.
  77.  * 
  78.  * Revision 4.4  87/12/18  11:44:47  narten
  79.  * fixed to use "varargs" in "fprintf"; this is required if it is to
  80.  * work on a SPARC machine such as a Sun-4
  81.  * 
  82.  * Revision 4.3  87/10/18  10:37:18  narten
  83.  * Updating version numbers. Changes relative to 1.1 actually relative
  84.  * to version 4.1
  85.  * 
  86.  * Revision 1.3  87/09/24  14:00:17  narten
  87.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  88.  * warnings)
  89.  * 
  90.  * Revision 1.2  87/03/27  14:22:33  jenkins
  91.  * Port to suns
  92.  * 
  93.  * Revision 4.1  83/03/25  18:12:51  wft
  94.  * Only changed $Header to $Id.
  95.  * 
  96.  * Revision 3.3  82/12/10  16:22:37  wft
  97.  * Improved error messages, changed exit status on error to 1.
  98.  *
  99.  * Revision 3.2  82/11/28  21:27:10  wft
  100.  * Renamed ctab to map and included EOFILE; ctab is now a macro in rcsbase.h.
  101.  * Added fflsbuf(), fputs(), and fprintf(), which abort the RCS operations
  102.  * properly in case there is an IO-error (e.g., file system full).
  103.  *
  104.  * Revision 3.1  82/10/11  19:43:56  wft
  105.  * removed unused label out:;
  106.  * made sure all calls to getc() return into an integer, not a char.
  107.  */
  108.  
  109.  
  110. /*
  111. #define LEXDB
  112. */
  113. /* version LEXDB is for testing the lexical analyzer. The testprogram
  114.  * reads a stream of lexemes, enters the revision numbers into the
  115.  * hashtable, and prints the recognized tokens. Keywords are recognized
  116.  * as identifiers.
  117.  */
  118.  
  119.  
  120.  
  121. #include "rcsbase.h"
  122.  
  123. libId(lexId, "$Id: rcslex.c,v 5.6 1991/01/30 14:21:32 apratt Exp $")
  124.  
  125. static struct hshentry *nexthsh;  /*pointer to next hash entry, set by lookup*/
  126.  
  127. enum tokens     nexttok;    /*next token, set by nextlex                    */
  128.  
  129. int             hshenter;   /*if true, next suitable lexeme will be entered */
  130.                             /*into the symbol table. Handle with care.      */
  131. int             nextc;      /*next input character, initialized by Lexinit  */
  132.  
  133. unsigned long    rcsline;    /*current line-number of input            */
  134. int             nerror;     /*counter for errors                            */
  135. int             quietflag;  /*indicates quiet mode                          */
  136. FILE *          finptr;     /*input file descriptor                         */
  137.  
  138. FILE *          frewrite;   /*file descriptor for echoing input             */
  139.  
  140. FILE *        foutptr;        /* copy of frewrite, but NULL to suppress echo  */
  141.  
  142. static struct buf tokbuf;   /* token buffer                    */
  143.  
  144. const char *    NextString; /* next token                    */
  145.  
  146. /*
  147.  * Our hash algorithm is h[0] = 0, h[i+1] = 4*h[i] + c,
  148.  * so hshsize should be odd.
  149.  * See B J McKenzie, R Harries & T Bell, Selecting a hashing algorithm,
  150.  * Software--practice & experience 20, 2 (Feb 1990), 209-224.
  151.  */
  152. #ifndef hshsize
  153. #    define hshsize 511
  154. #endif
  155.  
  156. static struct hshentry *hshtab[hshsize]; /*hashtable                */
  157.  
  158. static int ignored_phrases; /* have we ignored phrases in this RCS file? */
  159.  
  160.     void
  161. warnignore()
  162. {
  163.     if (! (ignored_phrases|quietflag)) {
  164.     ignored_phrases = true;
  165.     warn("Unknown phrases like `%s ...;' are in the RCS file.", NextString);
  166.     }
  167. }
  168.  
  169.  
  170.  
  171.     static void
  172. lookup(str)
  173.     const char *str;
  174. /* Function: Looks up the character string pointed to by str in the
  175.  * hashtable. If the string is not present, a new entry for it is created.
  176.  * In any case, the address of the corresponding hashtable entry is placed
  177.  * into nexthsh.
  178.  */
  179. {
  180.     register unsigned ihash;  /* index into hashtable */
  181.     register const char *sp;
  182.     register struct hshentry *n, **p;
  183.  
  184.         /* calculate hash code */
  185.     sp = str;
  186.         ihash = 0;
  187.     while (*sp)
  188.         ihash  =  (ihash<<2) + *sp++;
  189.     ihash %= hshsize;
  190.  
  191.     for (p = &hshtab[ihash];  ;  p = &n->nexthsh)
  192.         if (!(n = *p)) {
  193.             /* empty slot found */
  194.             *p = n = ftalloc(struct hshentry);
  195.             n->num = fstrsave(str);
  196.             n->nexthsh = nil;
  197. #            ifdef LEXDB
  198.                 VOID printf("\nEntered: %s at %u ", str, ihash);
  199. #            endif
  200.             break;
  201.         } else if (strcmp(str, n->num) == 0)
  202.             /* match found */
  203.             break;
  204.     nexthsh = n;
  205.     NextString = n->num;
  206. }
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.     void
  214. Lexinit()
  215. /* Function: Initialization of lexical analyzer:
  216.  * initializes the hashtable,
  217.  * initializes nextc, nexttok if finptr != NULL
  218.  */
  219. {       register int            c;
  220.  
  221.     for (c = hshsize;  0 <= --c;  ) {
  222.         hshtab[c] = nil;
  223.         }
  224.  
  225.     hshenter=true; rcsline=1; nerror=0;
  226.     ignored_phrases = false;
  227.     bufrealloc(&tokbuf, 2);
  228.         if (finptr) {
  229.         GETC(finptr,foutptr,c);
  230.         nextc = c; /*initial character*/
  231.         nexttok = DELIM;  /* anything but EOFILE */
  232.                 nextlex();            /*initial token*/
  233.         } else {
  234.                 nextc = '\0';
  235.                 nexttok=EOFILE;
  236.         }
  237. }
  238.  
  239.  
  240.     static exiting void
  241. unexpectedEOF()
  242. {
  243.     fatserror("unexpected EOF");
  244. }
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.     void
  253. nextlex()
  254.  
  255. /* Function: Reads the next token and sets nexttok to the next token code.
  256.  * Only if hshenter is set, a revision number is entered into the
  257.  * hashtable and a pointer to it is placed into nexthsh.
  258.  * This is useful for avoiding that dates are placed into the hashtable.
  259.  * For ID's and NUM's, NextString is set to the character string.
  260.  * Assumption: nextc contains the next character.
  261.  */
  262. {       register c;
  263.     register FILE * fin, * frew;
  264.         register char * sp;
  265.     const char *lim;
  266.         register enum tokens d;
  267.  
  268.     if (nexttok == EOFILE)
  269.         unexpectedEOF();
  270.     fin=finptr; frew=foutptr;
  271.